//
//  AQTaskBlock.m
//  RunLoopDemo
//
//  Created by zhangjikuan on 2020/8/27.
//  Copyright © 2020 hsgd. All rights reserved.
//

#import "AQTaskBlock.h"

typedef void(^GloableBlock)(void);

@implementation AQTaskBlock
- (void)execute {
    // block 分为堆区block 栈区block 数据区block
    // 每个block有不一样的
    
    [self testBlock:^{
        NSLog(@"testBlock");
    }];
    
    // 实验特性一 捕获变量
    int age = 10;
    void (^block)(void) = ^{
        NSLog(@"age is %d", age);
    };
    
    age = 20;
    block();
    
    /**
     输出值为 age：10
     原因：创建block的时候，已经把age的值存储在里面了。
     */
    
    auto int age2 = 10;
    
    static int num = 25;
    
    void(^Block)(void) = ^{
        NSLog(@"age: %d, num: %d", age2, num);
    };
    age2 = 20;
    num = 11;
    Block();
    /**
     输出结果为：age:10,num:11
     愿意：auto变量block访问方式是值传递，static变量block访问方式是指针传递
     源码证明：
     int age = __cself->age; // bound by copy
     int *num = __cself->num; // bound by copy

     NSLog((NSString *)&__NSConstantStringImpl__var_folders_2r__m13fp2x2n9dvlr8d68yry500000gn_T_main_d2875b_mi_0, age, (*num));

     int age = 10;
     static int num = 25;

     block = ((void (*)())&__test_block_impl_0((void *)__test_block_func_0, &__test_block_desc_0_DATA, age, &num));

     age = 20;
     num = 11;
     */

    [self testBlockType];
    
    
}

/// 测试block三种类型
- (void)testBlockType {
    int age = 1;
    void (^block1)(void) = ^{
        NSLog(@"block1");
    };

    void (^block2)(void) = ^{
        NSLog(@"block2:%d",age);
    };

    NSLog(@"%@/%@/%@",[block1 class],[block2 class],[^{
        NSLog(@"block3:%d",age);
    } class]);
    
    
}

- (void)testBlock:(GloableBlock) block {
    if (block) {
        block();
    }
}
@end

